#include <stdio.h>
#include <string.h>
#include <windows.h>
#include <time.h>
#include <stdlib.h>
#include <conio.h>

#define size 3

typedef struct Snake
{
	int x;
	int y;
	struct Snake *next;
} Snake, *pSnake;

int fx, fy;

int score = -5;

pSnake head;

//游戏开始欢迎界面
void meun();

//画墙
void printWall();

//初始化蛇身
void init();

//随机函数
void random(int *x, int *y);

//坐标函数
void pos(int x, int y);

//打印蛇身
void print();

//蛇动
void move();

//清除光标
void HideCursor();

//产生食物
void Cfood();

//判断是否在蛇身上
int isIn(int x, int y);

//判断食物是否被吃
int isFood();

//蛇的增长
void addSnake();

//蛇的死亡
int isDe();

//增加积分
void add();

//颜色
int color(int num);

//已经死了
void death();

char flag = 77;

int main ()
{
	int i;

	HideCursor();
	for (int i = 1; i <= 7; i++)
	{
		system("cls");
		color(i);
		i %= 7;
		meun();
		Sleep(500);
		if (kbhit())
		{
			break;
		}
	}

	system("cls");
	printWall();
	init();
	print();
	Cfood();
	add();
	while (1)
	{
		fflush(stdin);
		move();
		if (isDe() == 1)
		{
			break;
		}
		Sleep(100);
		if (kbhit())
		{
			flag = _getch();
		}
	}
	death();
}

//游戏开始欢迎界面
void meun()
{

	printf("                                                                                         \n");
	printf("                       __________       ___                                              \n");
	printf("                      /          \\     / \\ \\    |____      __\\__                     \n");
	printf("                     /  ________  \\   / ___ \\  _/ __     | |   /                       \n");
	printf("                     |  |      |__|     _/_   |_|  /    [|] |/                           \n");
	printf("                     |  |              | | |      /     _|_ \\__/                        \n");
	printf("                     \\  \\_______        / \\      |___/        ____                    \n");
	printf("                      \\         \\    ____ ____      ____   __ |  |  ___   ______       \n");
	printf("                       \\_______  \\   |  |/    \\    /    \\_/ / |  | /  /  /      \\   \n");
	printf("                               \\  \\  |    ___  \\  / ____   /  |  |/  /  /  ____  \\   \n");
	printf("                     __        |  |  |   /   \\  \\ | |  |  /   |     /  |  /____\\  |   \n");
	printf("                    \\  \\_______|  |  |  |    |  | | |__|  |   |     \\  |  ________/   \n");
	printf("                     \\            /  |  |    |  |  \\       \\  |  |\\  \\  \\  \\____  \n");
	printf("                      \\__________/   |__|    |__|   \\___/\\__\\ |__| \\__\\  \\______/ \n");
	printf("四个方向键控制蛇的移动方向\n");
	printf("按回车键开始游戏");
}

//初始化蛇身
void init()
{
	pSnake tmp = (pSnake)malloc(sizeof(Snake));
	tmp->next = NULL;
	head = tmp;
	tmp->x = 30;
	tmp->y = 10;
	for (int i = 1; i < size; i++)
	{
		pSnake temp = (pSnake)malloc(sizeof(Snake));
		temp->next = NULL;
		tmp->next = temp;
		temp->x = tmp->x - 2;
		temp->y = tmp->y;
		tmp = tmp->next;
	}
}


//坐标函数
void pos(int x, int y)
{
	COORD c;
	c.X = x;
	c.Y = y;
	SetConsoleCursorPosition (GetStdHandle(STD_OUTPUT_HANDLE), c);
}

//画墙
void printWall()
{
	color(2);
	for (int i = 0; i <= 80; i += 2)
	{
		pos(i, 0);
		printf("■");
		pos(i, 26);
		printf("■");
	}

	for (int i = 0; i <= 26; i++)
	{
		pos(0, i);
		printf("■");
		pos(80, i);
		printf("■");
	}

}

//打印蛇身
void print()
{
	color(5);
	pSnake tmp = head;
	while (tmp != NULL)
	{
		pos(tmp->x, tmp->y);
		printf("■");
		tmp = tmp->next;
	}
}

//蛇动
void move()
{
	if (flag == 77 || flag == 72 || flag == 80 || flag == 75)
	{

	}
	else
	{
		return;
	}
	//增加头
	pSnake temp = (pSnake)malloc(sizeof(Snake));
	temp->next = head;
	head = temp;

	if (flag == 77) //右
	{
		temp->x = temp->next->x + 2;
		temp->y = temp->next->y;
	}
	else if (flag == 72)	//上
	{
		temp->x = temp->next->x;
		temp->y = temp->next->y - 1;
	}
	else if (flag == 80)
	{
		temp->x = temp->next->x;
		temp->y = temp->next->y + 1;
	}
	else if (flag == 75)
	{
		temp->x = temp->next->x - 2;
		temp->y = temp->next->y;
	}

	if (isFood() == 1)
	{
		return;
	}
	//删尾巴
	pSnake tmp = head;
	while (tmp->next->next != NULL)
	{
		tmp = tmp->next;
	}
	pos(tmp->next->x, tmp->next->y);
//	free(tmp->next);
	printf("  ");

	tmp->next = NULL;

	print();
}

//隐藏光标
void HideCursor()
{
	CONSOLE_CURSOR_INFO curInfo; //定义光标信息的结构体变量
	curInfo.dwSize = 1; //如果没赋值的话，光标隐藏无效
	curInfo.bVisible = FALSE; //将光标设置为不可见
	HANDLE handle = GetStdHandle(STD_OUTPUT_HANDLE); //获取控制台句柄
	SetConsoleCursorInfo(handle, &curInfo); //设置光标信息
}

//产生食物
void Cfood()
{
	color(4);
	int x, y;
	random(&x, &y);
	if ((x >= 2 && x <= 78) && (y <= 25 && y >= 1))	//在墙里面
	{
		if (isIn(x, y) == 0) //不在蛇内
		{
			fx = x;
			fy = y;
			pos(x, y);
			printf("★");
			return;
		}
	}
	Cfood();
}

//判断是否在蛇身上
int isIn(int x, int y)
{
	pSnake tmp = head;
	while (tmp != NULL)
	{
		if (tmp->x == x && tmp->y == y)
		{
			return 1;
		}
		tmp = tmp->next;
	}
	return 0;
}

//随机函数
void random(int *x, int *y)
{
	srand((unsigned)time(NULL));
//	2~78			1~39
	int a = rand() % 39 + 1;
	int b = rand() % 25 + 1;
	*x = a * 2;
	*y = b;
}

//判断食物是否被吃
int isFood()
{
	pSnake tmp = head;
	if (tmp->x == fx && tmp->y == fy)
	{
		Cfood();
		add();
		return 1;
	}
	return 0;
}

//蛇的增长
void addSnake()
{
	pSnake tmp = head;
	while (tmp->next != NULL)
	{
		tmp = tmp->next;
	}
	pSnake temp = (pSnake)malloc(sizeof(Snake));
	tmp->next = temp;
	temp->next = NULL;
}

//蛇的死亡
int isDe()
{
	pSnake tmp = head;
	if (tmp->x == 0 || tmp->x == 80 || tmp->y == 0 || tmp->y == 26)
	{
		return 1;
	}
	tmp = tmp->next;
	while (tmp != NULL)
	{
		if (head->x == tmp->x && head->y == tmp->y)
		{
			return 1;
		}
		tmp = tmp->next;
	}
	return 0;
}

//增加积分
void add()
{
	score += 5;
	pos(90, 15);
	printf("您现在的积分是：%d", score);
}


//颜色
int color(int num)
{
	SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), num);
	return 0;

}

//已经死了
void death()
{
	system("cls");
	pos(40, 15);
	printf("您获得的分数是:%d", score);
	pos(40, 16);
	if (score <= 20)
	{
		printf("你已经死亡,真是个垃圾");
	}
	else if (score <= 30)
	{
		printf("呦呵小伙子有点东西");
	}
	else if (score <= 40)
	{
		printf("传说中的训蛇大师");
	}
	else if (score > 40)
	{
		printf("你就是神!!!!");
	}
	else if (score > 100)
	{
		printf("超越神啦!!!!!!!!!!");
	}
	getchar();
}
